﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using Microsoft.EnterpriseManagement;
using Microsoft.EnterpriseManagement.Common;
using Microsoft.EnterpriseManagement.Configuration;
using Microsoft.EnterpriseManagement.Administration;
using Microsoft.EnterpriseManagement.Monitoring;
using System.Collections.ObjectModel;
namespace scomConsoleMM
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                switch (args[0])
                {
                    case "startObjectMM":
                        try
                        {
                            DateTime startTime = DateTime.Now;
                            int numMinutes = Convert.ToInt32(args[4]);
                            DateTime endTime = DateTime.Now.AddMinutes(numMinutes);
                            bool recurse = Convert.ToBoolean(args[7]);
                            string[] DisplayNameList = args[1].Split(',');
                            foreach(String DisplayName in DisplayNameList)
                                putObjectInMM(DisplayName, args[2], args[3], startTime, endTime, args[5], args[6], recurse);
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("startObjectMM DisplayName RMS Class MinutesToAdd ReasonCategory Comments Recurse");
                        }
                        break;
                    case "stopObjectMM":
                        try
                        {
                            string[] DisplayNameList = args[1].Split(',');
                            foreach (String DisplayName in DisplayNameList)
                                stopObjectMM(DisplayName, args[2], args[3]);
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("stopObjectMM DisplayName RMS Class");
                        }
                        break;
                    case "getObjectMM":
                        try
                        {
                            string[] DisplayNameList = args[1].Split(',');
                            foreach (String DisplayName in DisplayNameList)
                                checkObjectMM(DisplayName, args[2], args[3]);
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("getObjectMM DisplayName RMS Class");
                        }
                        break;
                    default:
                        Console.WriteLine("startObjectMM DisplayName RMS Class MinutesToAdd ReasonCategory Comments Recurse");
                        Console.WriteLine("stopObjectMM DisplayName RMS Class");
                        Console.WriteLine("getObjectMM DisplayName RMS Class");
                        break;
                }
            }
            catch (Exception)
            {
                Console.WriteLine("startObjectMM DisplayName RMS Class MinutesToAdd ReasonCategory Comments Recurse");
                Console.WriteLine("stopObjectMM DisplayName RMS Class");
                Console.WriteLine("getObjectMM DisplayName RMS Class");
            }
        }

        private static void putObjectInMM(String DisplayName, String RMS, String Class, DateTime StartTime, DateTime EndTime, String ReasonCategory, String Reason, bool recurse)
        {
            try
            {
                ManagementGroup mg = new ManagementGroup(RMS);
                MonitoringClass mc = mg.GetMonitoringClass(SystemMonitoringClass.WindowsComputer);
                ReadOnlyCollection<MonitoringClass> MonClassColl = mg.GetMonitoringClasses(Class);
                if (MonClassColl.Count > 0)
                    mc = MonClassColl[0];
                else
                    Console.WriteLine("Could not find class " + Class);
                String query = "DisplayName = '" + DisplayName + "'";

                MonitoringObjectGenericCriteria criteria = new MonitoringObjectGenericCriteria(query);
                List<MonitoringObject> monObjects = new List<MonitoringObject>();
                monObjects.AddRange(mg.GetMonitoringObjects(criteria, mc));

                if (monObjects.Count == 1)
                {
                    foreach (MonitoringObject monObject in monObjects)
                    {
                        if (monObject.InMaintenanceMode)
                        {
                            Console.WriteLine(monObject.DisplayName + " is already in Maintenance Mode.");
                        }
                        else
                        {
                            StartTime = StartTime.ToUniversalTime();
                            EndTime = EndTime.ToUniversalTime();

                            MaintenanceModeReason reason = MaintenanceModeReason.UnplannedOther;
                            switch (ReasonCategory)
                            {
                                case "ApplicationInstallation":
                                    reason = MaintenanceModeReason.ApplicationInstallation;
                                    break;
                                case "ApplicationUnresponsive":
                                    reason = MaintenanceModeReason.ApplicationUnresponsive;
                                    break;
                                case "ApplicationUnstable":
                                    reason = MaintenanceModeReason.ApplicationUnstable;
                                    break;
                                case "LossOfNetworkConnectivity":
                                    reason = MaintenanceModeReason.LossOfNetworkConnectivity;
                                    break;
                                case "PlannedApplicationMaintenance":
                                    reason = MaintenanceModeReason.PlannedApplicationMaintenance;
                                    break;
                                case "PlannedHardwareInstallation":
                                    reason = MaintenanceModeReason.PlannedHardwareInstallation;
                                    break;
                                case "PlannedHardwareMaintenance":
                                    reason = MaintenanceModeReason.PlannedHardwareMaintenance;
                                    break;
                                case "PlannedOperatingSystemReconfiguration":
                                    reason = MaintenanceModeReason.PlannedOperatingSystemReconfiguration;
                                    break;
                                case "PlannedOther":
                                    reason = MaintenanceModeReason.PlannedOther;
                                    break;
                                case "SecurityIssue":
                                    reason = MaintenanceModeReason.SecurityIssue;
                                    break;
                                case "UnplannedApplicationMaintenance":
                                    reason = MaintenanceModeReason.UnplannedApplicationMaintenance;
                                    break;
                                case "UnplannedHardwareInstallation":
                                    reason = MaintenanceModeReason.UnplannedHardwareInstallation;
                                    break;
                                case "UnplannedHardwareMaintenance":
                                    reason = MaintenanceModeReason.UnplannedHardwareMaintenance;
                                    break;
                                case "UnplannedOperatingSystemReconfiguration":
                                    reason = MaintenanceModeReason.UnplannedOperatingSystemReconfiguration;
                                    break;
                                case "UnplannedOther":
                                    reason = MaintenanceModeReason.UnplannedOther;
                                    break;
                                default:
                                    reason = MaintenanceModeReason.UnplannedOther;
                                    break;
                            }
                            if (recurse)
                            {
                                monObject.ScheduleMaintenanceMode(StartTime, EndTime, reason, Reason, TraversalDepth.Recursive);
                            }
                            else
                                monObject.ScheduleMaintenanceMode(StartTime, EndTime, reason, Reason);

                            Console.WriteLine(monObject.DisplayName + " is now in Maintenance Mode");
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Did not find " + DisplayName);
                }
            
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed to put " + DisplayName + " into Maintenance Mode \n" + ex.Message.ToString());
            }
        }
        private static void checkObjectMM(String DisplayName, String RMS, String Class)
        {
            try
            {
                ManagementGroup mg = new ManagementGroup(RMS);
                MonitoringClass mc = mg.GetMonitoringClass(SystemMonitoringClass.WindowsComputer);
                ReadOnlyCollection<MonitoringClass> MonClassColl = mg.GetMonitoringClasses(Class);
                if (MonClassColl.Count > 0)
                    mc = MonClassColl[0];
                else
                    Console.WriteLine("Could not find class " + Class);

                String query = "DisplayName = '" + DisplayName + "'";

                MonitoringObjectGenericCriteria criteria = new MonitoringObjectGenericCriteria(query);
                List<MonitoringObject> monObjects = new List<MonitoringObject>();
                monObjects.AddRange(mg.GetMonitoringObjects(criteria, mc));

                if (monObjects.Count == 1)
                {
                    foreach (MonitoringObject monObject in monObjects)
                    {
                        if (monObject.InMaintenanceMode)
                        {
                            MaintenanceWindow window = monObject.GetMaintenanceWindow();
                            DateTime schedEndTime = window.ScheduledEndTime;
                            DateTime startTime = window.StartTime;
                            String user = window.User;
                            String comments = window.Comments;
                            Console.WriteLine(monObject.DisplayName + " in maintenance mode" + "\n");
                            Console.WriteLine("User:\t\t" + user);
                            Console.WriteLine("Start Time:\t" + startTime.ToLocalTime().ToShortDateString() + " " + startTime.ToLocalTime().ToLongTimeString());
                            Console.WriteLine("End Time:\t" + schedEndTime.ToLocalTime().ToShortDateString() + " " + schedEndTime.ToLocalTime().ToLongTimeString());
                            Console.WriteLine("Comments:\t" + comments);
                        }
                        else
                        {
                            Console.WriteLine(monObject.DisplayName + " is not in Maintenance mode");
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Did not find " + DisplayName);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed to get Maintenance Mode information \n" + ex.Message.ToString());
            }
        }
        private static void stopObjectMM(String DisplayName, String RMS, String Class)
        {
            String query = "DisplayName = '" + DisplayName + "'";
            try
            {
                ManagementGroup mg = new ManagementGroup(RMS);
                MonitoringClass mc = mg.GetMonitoringClass(SystemMonitoringClass.WindowsComputer);
                ReadOnlyCollection<MonitoringClass> MonClassColl = mg.GetMonitoringClasses(Class);
                if (MonClassColl.Count > 0)
                    mc = MonClassColl[0];
                else
                    Console.WriteLine("Could not find class " + Class);

                MonitoringObjectGenericCriteria criteria = new MonitoringObjectGenericCriteria(query);
                List<MonitoringObject> monObjects = new List<MonitoringObject>();
                monObjects.AddRange(mg.GetMonitoringObjects(criteria, mc));

                if (monObjects.Count == 1)
                {
                    foreach (MonitoringObject monObject in monObjects)
                    {
                        if (monObject.InMaintenanceMode)
                        {
                            monObject.StopMaintenanceMode(DateTime.UtcNow, TraversalDepth.Recursive);

                            Console.WriteLine(monObject.DisplayName + " is now out of Maintenance Mode.");
                        }
                        else
                        {
                            Console.WriteLine(monObject.DisplayName + " was not in Maintenance Mode.");
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Did not find " + DisplayName);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed to Stop Maintenance Mode on " + DisplayName + "\n" + ex.Message.ToString());
            }
        }
    }
}
